/*
* 1.无向图 双连通分量
    (1) 边的双连通分量  e-dcc  极大的不包含桥的连通块
    (2) 点的双连通分量  v-dcc  极大的不包含割点的连通块

* 2. 什么是桥, 如何找桥？ 
    桥: 删掉该边, 连通分量数量改变
    割点: 删掉该点以及附属边, 连通分量数量改变
    x和y之间是桥 <-> dfn[x] < low[y] y无论如何往上走不到x 
                    +y能到的最高的点low[y] = dfn[y]

    每个割点至少属于两个连通分量
    树里的每条边都是桥
 
* 3.如何找所有边的双连通分量？
        将所有桥删掉
        dfn[x] == low[x] 
        <-> x无论如何走不到x的上面
        <-> 从x开始的子树可以用一个栈存

* 本题: 
    首先用tarjan算法把图中所有双联通分量缩成点
    无向图点双联通分量：不存在割点的子图
    注意这里的割点指的是删掉之后子图不连通而不是整幅图不连通
    
    答案1:
    我们把所有的块分成三类

        1.没有割点的块
            这种块是孤立的

            所以需要在块内两个不同节点上建两个出口

            （任意一个塌了可以用另外一个）

            还要特判一下：如果只有一个点的话建一个出口就行

        2.有一个割点的块
            比如上图中红色和绿色的块

            这种块要在除割点外任意一点建一个出口

            这样如果割点塌了，可以用那个出口

            如果出口塌了可以通过割点去到别的块

        3.有两个或以上割点的块
            比如上图中蓝色和黄色的块

            这种块是不需要出口的

            不难发现，不管哪个点塌了，都可以通过没塌的割点去到别的块

    答案2:
        1.没有割点的块
            如果只包含一个节点的话，相当于ans2×1，是没有任何贡献的

            否则可以在任意两个点建立出口

            答案乘上 点数×（点数-1）÷2

        2.有一个割点的块
            在除割点外任意一点建出口

            答案乘上 点数-1

        3.有两个或以上割点的块
            这种块不会建任何出口

            所以对答案没有贡献

            判断一个点是否为割点
            每次tarjan都会有一个遍历的初始节点，记为root

            low[i]代表i的子节点向上（按层数算）最高能到哪个点

            可以把一个割点分为是root和不是root两类

            不是root的可以直接判断（y是x的一个子节点）

            if(x!=root&&low[y]>=x)
            是root的需要开一个cnt记录一下下面有几个块

*/

#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
// #define ONLINE_GUDGE
using namespace std;
using LL = unsigned long long;
const int N = 1010, M = 510, INF = 0x3f3f3f3f;

int n, m;
int h[N], e[M], ne[M], idx;
int dfn[N], low[N], timestamp; // dfs序 最小访问时间 时间戳
// int stk[N], top; // 栈 栈顶指针
stack<int> stk; // 内置DS优化
bool cut[N]; // 判断结点是否是割点
int dcc_cnt; // id数组存储每个点所在的连通分量编号 Double Connected Component sze数组统计每个连通分量的点的数量
vector<int> dcc[N]; // 存每个块的所有点
int root, cnt; // 当前遍历的起始节点 块数

void AddEdge(int a, int b) // , int c)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++; // w[idx] = c,  
}

void Tarjan(int u){ 
    dfn[u] = low[u] = ++timestamp;
    // stk[ ++ top ] = u, in_stk[u] = true;
     
    stk.push(u); 
    // in_stk[u] = true;
    if(u == root && h[u] == -1)
    {
        dcc_cnt++;
        dcc[dcc_cnt].push_back(u);
        return;
    }

    int cnt = 0; // u 有多少分支
    for(int i = h[u]; ~i; i = ne[i]){
        int v = e[i];
        if(!dfn[v]){
            Tarjan(v);
            low[u] = min(low[u], low[v]); // 用u的邻点j更新u所能到达的结点最小时间戳
            if(dfn[u] <= low[v]) // 表示v节点永远都走不到u节点(u,v这两个点只能从u走到v)，所以边u-v(w[i])是一条桥边
            {
                cnt++;
                if(u != root || cnt > 1) cut[u] = true;
                ++dcc_cnt;
                int y;
                do{
                    // y = stk[ top -- ];
                    y = stk.top(); stk.pop();
                    dcc[dcc_cnt].push_back(y);
                }while(y != v); // 直至取完
                dcc[dcc_cnt].push_back(u);
            }    
        }
        else low[u] = min(low[u], dfn[v]);
    }
}

int main()
{

    #ifdef ONLINE_JUDGE

    #else
    freopen("./in.txt","r",stdin);
    #endif
    //ios::sync_with_stdio(false);   
	//cin.tie(0);
    
    int T = 1;
    while(cin >> m, m)
    {
        for (int i = 1; i <= dcc_cnt; i ++ ) dcc[i].clear();

        idx = n = timestamp = dcc_cnt = 0;
        memset(h, -1, sizeof h);
        memset(dfn, 0, sizeof dfn);
        memset(cut, 0, sizeof cut);

        while(m--)
        {
            int a, b; cin >> a >> b;
            n = max(n, max(a, b));
            AddEdge(a, b); AddEdge(b, a);
        }

        for(root = 1; root <= n; root++)
            if(!dfn[root]){
                Tarjan(root);
            } 
        
        int res = 0; LL num = 1;
        for(int u = 1; u <= dcc_cnt; u++)
        {
            int cnt = 0;
            for(int i = 0; i < dcc[u].size(); i++)
                if(cut[dcc[u][i]]) cnt++;

            //无割点
            if(!cnt)
            {
                //随便选两个点放
                if(dcc[u].size()>1) res += 2, num *= dcc[u].size() * (dcc[u].size()-1) / 2;

                //就只有一个点
                else res++;
            }

            //只有一个割点，随便选一个点放即可（割点除外）
            else if(cnt==1) res++,num*=dcc[u].size()-1;
            
        }
        printf("Case %d: %d %llu\n", T++, res, num); //输出答案
    }

    return 0;
}